﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace DataCollectionSystem.MenuBar
{
    internal class TcpCommunication
    {
        private TcpListener listener; // 监听器
        private TcpClient client; // 客户端连接
        public NetworkStream stream; // 网络流对象

        private int heartbeatInterval = 5000; // 心跳检测时间间隔
        private byte[] heartBeatMsg = Encoding.ASCII.GetBytes("I am alive!"); // 心跳消息内容
        private DateTime lastHeartBeatTime; // 上次接收到心跳消息的时间

        //线程锁（注意!!!!!）
        private static object myLock = new object();

        //存放所有的网络流对象
        public Dictionary<string, NetworkStream> TcpKeyValue = new Dictionary<string, NetworkStream>();

        //存放所有的客户端连接Client
        private List<TcpClient> ClientList = new List<TcpClient>();

        // 事件委托和事件定义
        public delegate void MessageReceivedEventHandler(string message);

        public event MessageReceivedEventHandler OnMessageReceived;

        public delegate void ClientDisconnectedEventHandler(string IP, int prot);

        public event ClientDisconnectedEventHandler OnClientDisconnected;

        // 启动监听器并等待客户端连接
        public void Start(string localIP, int port)
        {
            listener = new TcpListener(IPAddress.Parse(localIP), port);
            listener.Start();

            Console.WriteLine("等待客户端连接...");

            while (true) // 循环等待新的客户端连接
            {
                client = listener.AcceptTcpClient(); // 接受客户端连接请求

                ClientList.Add(client);

                stream = client.GetStream(); // 获取网络流对象

                IPEndPoint remoteIpEndpoint = (IPEndPoint)client.Client.RemoteEndPoint;
                string remoteIpAddress = remoteIpEndpoint.Address.ToString();
                int remotePort = remoteIpEndpoint.Port;

                Console.WriteLine(remoteIpAddress + " " + remotePort);
                lock (myLock)
                {
                    if (!TcpKeyValue.ContainsKey(remoteIpAddress))
                    {
                        TcpKeyValue.Add(remoteIpAddress, stream);
                    }
                    else
                    {
                        TcpKeyValue[remoteIpAddress] = stream;
                    }
                }

                Console.WriteLine("客户端已连接");

                // 初始化心跳检测时间
                lastHeartBeatTime = DateTime.Now;

                // 创建一个新线程处理客户端请求
                Thread t = new Thread(new ThreadStart(HandleClientComm));
                t.Start();

                //启动心跳包线程
                //Thread heartbeatThread = new Thread(SendHeartbeat);
                //heartbeatThread.IsBackground = true;
                //heartbeatThread.Start();
            }
        }

        // 处理客户端消息的方法
        private void HandleClientComm()
        {
            while (true) // 循环接收客户端消息
            {
                // 接收客户端消息
                byte[] buffer = new byte[1024];
                int bytesRead = stream.Read(buffer, 0, buffer.Length);

                if (bytesRead == 0) // 客户端已断开连接
                {
                    IPEndPoint remoteIpEndpoint = (IPEndPoint)client.Client.RemoteEndPoint;
                    string remoteIpAddress = remoteIpEndpoint.Address.ToString();
                    int remotePort = remoteIpEndpoint.Port;

                    OnClientDisconnected?.Invoke(remoteIpAddress, remotePort); // 触发客户端断开连接事件
                    ClientList.Remove(client);
                    TcpKeyValue.Remove(remoteIpAddress);
                    break;
                }

                string data = Encoding.ASCII.GetString(buffer, 0, bytesRead);

                //接收到消息
                OnMessageReceived?.Invoke(data); // 触发收到消息事件

                // 发送响应消息给客户端
                //byte[] response = System.Text.Encoding.ASCII.GetBytes("我已经收到你的消息了！");

                //stream.Write(response, 0, response.Length);
            }
            //client.Dispose();
            client.Close();
        }

        //发送心跳
        private void SendHeartbeat()
        {
            while (true)
            {
                byte[] heartbeat = Encoding.UTF8.GetBytes("heartbeat");

                foreach (KeyValuePair<string, NetworkStream> pair in TcpKeyValue)
                {
                    Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
                    try
                    {
                        // 在这里调用 Write 方法
                        pair.Value.Write(heartBeatMsg, 0, heartBeatMsg.Length);
                    }
                    catch
                    {
                        IPEndPoint remoteIpEndpoint = (IPEndPoint)client.Client.RemoteEndPoint;
                        string remoteIpAddress = remoteIpEndpoint.Address.ToString();
                        int remotePort = remoteIpEndpoint.Port;

                        OnClientDisconnected?.Invoke(remoteIpAddress, remotePort);
                        //获取引起异常的 TcpClient 对象
                        //TcpClient client = (TcpClient)ex.SocketErrorCode;

                        //获取连接断开的客户端的 IP 地址
                        //string clientIP = ((IPEndPoint)client.RemoteEndPoint).Address.ToString();

                        //输出客户端 IP 地址
                        //Console.WriteLine("客户端 {0} 连接已断开", clientIP);
                    }
                }

                Thread.Sleep(heartbeatInterval); // 每隔 5 秒发送一次心跳包
            }
        }

        //结束所有的客户端
        public void ClientDispose()
        {
            foreach (KeyValuePair<string, NetworkStream> pair in TcpKeyValue)
            {
                pair.Value.Close();
            }
            foreach (TcpClient client in ClientList)
            {
                client.Close();
            }
        }
    }
}